package com.wondertek.poms.core.service.impl;

import com.wondertek.poms.common.constant.Constants;
import com.wondertek.poms.common.exception.BusinessException;
import com.wondertek.poms.common.exception.MessageCodes;
import com.wondertek.poms.core.manager.InPrdInfoManager;
import com.wondertek.poms.core.service.IPlanMoveCronTaskService;
import com.wondertek.poms.dao.po.Content;
import com.wondertek.poms.dao.po.ContentBlack;
import com.wondertek.poms.dao.po.ContentWhite;
import com.wondertek.poms.dao.po.PlanMovePrdInfo;
import com.wondertek.poms.dao.po.PrdCont;
import com.wondertek.poms.dao.po.PrdInfo;
import com.wondertek.poms.dao.repo.IContentBlackDao;
import com.wondertek.poms.dao.repo.IContentDao;
import com.wondertek.poms.dao.repo.IContentWhiteDao;
import com.wondertek.poms.dao.repo.IPlanMovePrdInfoDao;
import com.wondertek.poms.dao.repo.IPrdContDao;
import com.wondertek.poms.dao.repo.IPrdInfoDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author evan0213
 * @description
 */
@Service
@Slf4j
public class PlanMoveCronTaskServiceImpl implements IPlanMoveCronTaskService {
	@Autowired
	private IPlanMovePrdInfoDao planMovePrdInfoDao;
	@Autowired
	private IPrdContDao prdContDao;
	@Autowired
	private IContentDao contentDao;
	@Autowired
	private IPrdInfoDao prdInfoDao;
	@Autowired
	private IContentBlackDao contentBlackDao;
	@Autowired
	private IContentWhiteDao contentWhiteDao;
	@Autowired
	private InPrdInfoManager inPrdInfoManager;

	@Override
	public void planMove() {
		List<PlanMovePrdInfo> planMovePrdInfoList = planMovePrdInfoDao.findAllByStatus(String.valueOf(Constants.MOVE_STATUS_0), new Date());
		if (planMovePrdInfoList != null && planMovePrdInfoList.size() > 0) {
			log.info("需要进行计划移包的数量为：{}", planMovePrdInfoList.size());
			for (PlanMovePrdInfo planMovePrdInfo : planMovePrdInfoList) {
				updateStatus(planMovePrdInfo);
				if (planMovePrdInfo.getPrdContId() != null) {
					log.info("变更计划移包id{}状态为准备移动成功", planMovePrdInfo.getId());
					log.info("开始根据节目id进行计划移包|节目id为{}", planMovePrdInfo.getPrdContId());
					moveByPrdContId(planMovePrdInfo);
					log.info("结束根据节目id进行计划移包|节目id为{}", planMovePrdInfo.getPrdContId());
				} else {
					log.info("开始根据内容id进行计划移包|内容id为{}", planMovePrdInfo.getContentId());
					moveByContentId(planMovePrdInfo);
					log.info("结束根据内容id进行计划移包|内容id为{}", planMovePrdInfo.getContentId());
				}
			}
		}
	}

	/**
	 * @param planMovePrdInfo 根据内容id进行计划移包
	 */
	private void moveByContentId(PlanMovePrdInfo planMovePrdInfo) {
		String contentId = planMovePrdInfo.getContentId();
		Long newPrdInfoId = planMovePrdInfo.getNewPrdInfoId();
		Content content = contentDao.findByContentId(contentId);
		PrdInfo prdInfo = prdInfoDao.getByPrdInfoIdAndSystemFlag(newPrdInfoId);
		List<PrdCont> prdContList = new ArrayList<>();
		//入包前判斷
		String msg = inPrdInfoManager.inPrdInfoRule(content, prdInfo, prdContList);
		if (StringUtils.isNotBlank(msg)) {
			log.info("根据内容id移包失败{}", msg);
			planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_5));
			planMovePrdInfo.setEndTime(new Date());
			planMovePrdInfo.setDescribe(msg);
			planMovePrdInfoDao.save(planMovePrdInfo);
			return;
		}
		log.info("结束判断，进行入包操作");
		planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_2));
		planMovePrdInfoDao.save(planMovePrdInfo);
		//入包操作
		inPrdInfoManager.inPrdInfoProcess(content, prdInfo);
		// 子集入包
		inPrdInfoManager.subSetToNewPrdInfo(newPrdInfoId, prdContList, content);
		planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_3));
		planMovePrdInfo.setEndTime(new Date());
		planMovePrdInfo.setDescribe("节目移包成功");
		planMovePrdInfoDao.save(planMovePrdInfo);
	}

	/**
	 * @param planMovePrdInfo 节目id进行移包
	 */
	private void moveByPrdContId(PlanMovePrdInfo planMovePrdInfo) {
		Long prdContId = planMovePrdInfo.getPrdContId();
		PrdCont prdCont = prdContDao.findByPrdContId(prdContId);
		if (prdCont.getIsDelete() == 0 && prdCont.getFileAction() != 2) {
			log.info("节目非删除状态，可以进行移包");
			if ("7".equals(prdCont.getFormType())) {
				log.info("节目的剧集类型为子集，不能单独操作");
				endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980312);
				throw new BusinessException(MessageCodes.M980312);
			} else {
				log.info("节目的剧集类型非子集，可以操作");
				Long oldPrdInfoId = planMovePrdInfo.getOldPrdInfoId();
				Long newPrdInfoId = planMovePrdInfo.getNewPrdInfoId();
				PrdInfo oldPrdInfo = prdInfoDao.findByPrdInfoId(oldPrdInfoId);
				PrdInfo newPrdInfo = prdInfoDao.findByPrdInfoId(newPrdInfoId);
				Long oldProductPackageId = oldPrdInfo.getProductInfoPackageId();
				Long newProductPackageId = newPrdInfo.getProductInfoPackageId();
				if (oldProductPackageId == null && newProductPackageId == null) {
					log.info("中断移包，不支持跨产品/独立商品包移包");
					endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980308);
					throw new BusinessException(MessageCodes.M980308);
				} else if (oldProductPackageId != null && newProductPackageId != null) {
					if (oldProductPackageId.equals(newProductPackageId)) {
						log.info("新老二级产品相同，开始匹配黑白名单");
						String contentId = prdCont.getContentId();
						List<ContentBlack> contentBlacks = contentBlackDao.findAllByContentIdAndPrdInfoId(contentId, newPrdInfoId);
						if (contentBlacks != null && contentBlacks.size() > 0) {
							log.info("黑名单中存在相关记录，中断手动移包");
							endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980309);
							throw new BusinessException(MessageCodes.M980309);
						}
						List<ContentWhite> contentWhites = contentWhiteDao.findAllByContentIdAndPackageId(contentId, oldProductPackageId);
						if (contentWhites != null && contentWhites.size() > 0) {
							log.info("白名单中存在相关记录，中断手动移包");
							endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980310);
							throw new BusinessException(MessageCodes.M980310);
						}
						log.info("结束黑白名单匹配，进行移包操作");

						//更新计划移包状态为移动中
						planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_2));
						planMovePrdInfoDao.save(planMovePrdInfo);
//						Content content = contentDao.findByContentId(contentId);
						if (prdCont.getFormType().equalsIgnoreCase(Constants.ASSET_FORM_TYPE_6) ||
								prdCont.getFormType().equalsIgnoreCase(Constants.ASSET_FORM_TYPE_10) ||
								prdCont.getFormType().equalsIgnoreCase(Constants.ASSET_FORM_TYPE_14)) {
							moveSubsetsByPrdContId(prdCont, newPrdInfoId);
						} else {
							prdContDao.updatePrdInfoId(newPrdInfoId, prdContId);
							if (prdCont.getPublishNoVOMSStatus() == Constants.PRD_CONT_PUBLISH_STATUS_12) {
								prdContDao.updatePublishNoVOMSStatus(Constants.PRD_CONT_PUBLISH_STATUS_10, prdCont.getPrdContId());
							}
						}
						planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_3));
						planMovePrdInfo.setEndTime(new Date());
						planMovePrdInfo.setDescribe("节目移包成功");
						planMovePrdInfoDao.save(planMovePrdInfo);

					} else {
						log.info("中断移包，不支持跨产品/独立商品包移包");
						endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980308);
						throw new BusinessException(MessageCodes.M980308);
					}
				} else {
					log.info("中断移包，不支持跨产品/独立商品包移包");
					endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980308);
					throw new BusinessException(MessageCodes.M980308);
				}
			}
		} else {
			log.info("不是合法节目，无法进行移包");
			endPlanMoveProcess(planMovePrdInfo, MessageCodes.M980311);
			throw new BusinessException(MessageCodes.M980311);
		}


	}

	/**
	 * 移动子集
	 *
	 * @param prdCont      FORM_TYPE_6，10，14的节目
	 * @param newPrdInfoId 新的商品包id
	 */
	private void moveSubsetsByPrdContId(PrdCont prdCont, Long newPrdInfoId) {
		String contentId = prdCont.getContentId();
		Long oldPrdInfoId = prdCont.getPrdInfoId();
		List<PrdCont> subSetPrdContList = prdContDao.findAllSubSetPrdConts(contentId, oldPrdInfoId);
		log.info("开始移动子集，子集的数量为{}", subSetPrdContList.size());
		for (PrdCont cont : subSetPrdContList) {
			prdContDao.updatePrdInfoId(newPrdInfoId, cont.getPrdContId());
		}
		log.info("子集移动结束，移动壳");
		prdContDao.updatePrdInfoId(newPrdInfoId, prdCont.getPrdContId());
		log.info("将已发布的节目改为待发布状态");
		for (PrdCont cont : subSetPrdContList) {
			if (cont.getPublishNoVOMSStatus() == Constants.PRD_CONT_PUBLISH_STATUS_12) {
				prdContDao.updatePublishNoVOMSStatus(Constants.PRD_CONT_PUBLISH_STATUS_10, cont.getPrdContId());
			}
		}
		if (prdCont.getPublishNoVOMSStatus() == Constants.PRD_CONT_PUBLISH_STATUS_12) {
			prdContDao.updatePublishNoVOMSStatus(Constants.PRD_CONT_PUBLISH_STATUS_10, prdCont.getPrdContId());
		}

	}

	/**
	 * 变更状态为准备移动
	 *
	 * @param planMovePrdInfo 计划移包
	 */
	private void updateStatus(PlanMovePrdInfo planMovePrdInfo) {
		planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_1));
		planMovePrdInfo.setStartTime(new Date());
		planMovePrdInfoDao.save(planMovePrdInfo);
	}

	/**
	 * 结束计划移包
	 *
	 * @param planMovePrdInfo 计划移包
	 * @param code            code
	 */
	private void endPlanMoveProcess(PlanMovePrdInfo planMovePrdInfo, int code) {
		planMovePrdInfo.setStatus(String.valueOf(Constants.MOVE_STATUS_5));
		planMovePrdInfo.setDescribe(MessageCodes.get(code));
		planMovePrdInfo.setEndTime(new Date());
		planMovePrdInfoDao.save(planMovePrdInfo);
	}


}
